﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using Common;
using Controladores;
using Entidades;
using Entidades.Models;
using Web.Pages;

namespace Web.Helpers
{
    public class MailHelper
    {
        public enum DeliveryType
        {
            Mail = 1,
            Sms = 2
        }

        public class Delivery
        {
            public Delivery(DeliveryType deliveryType, Entidad entity)
            {
                this.DeliveryType = deliveryType;
                this.Entity = entity;
            }
            public DeliveryType DeliveryType { get; set; }
            public Entidad Entity { get; set; }
        }

        public class MailInternalData : IDisposable
        {
            public MailInternalData(int idEstudio, int idTipoNotificacion, DeliveryType deliveryType, object data)
            {
                this.IdEstudio = idEstudio;
                this.IdTipoNotificacion = idTipoNotificacion;
                this.DeliveryType = deliveryType;
                this.Data = data;
            }

            public int IdEstudio { get; set; }
            public int IdTipoNotificacion { get; set; }
            public DeliveryType DeliveryType { get; set; }
            public object Data { get; set; }

            private bool _disposed;
            protected virtual void Dispose(bool disposing)
            {
                if (!this._disposed)
                {
                    if (disposing)
                    {
                        if (this.Data != null)
                        {
                            var data = this.Data as IDisposable;
                            if (data != null)
                            {
                                // dispose managed resources
                                data.Dispose();
                            }
                        }
                    }
                }

                // dispose unmanaged resources
                this._disposed = true;
            }
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
        }

        #region Public Methods

        /// <summary>
        /// Returns a Dictionary(string, string) of Mail Address and Display Name
        /// </summary>
        /// <param name="mailAddress"></param>
        /// <param name="displayName"></param>
        /// <returns></returns>
        public static Dictionary<string, string> CreateRecipientsList(string mailAddress, string displayName)
        {
            return new Dictionary<string,string> { { mailAddress, displayName} };
        }

        /// <summary>
        /// Enviar Mail de recuperacion de Password de Usuario
        /// </summary>
        /// <param name="usuario"></param>
        /// <param name="idEstudio"></param>
        /// <returns></returns>
        public static bool EnviarMailRecuperacionPassword(Usuario usuario, int idEstudio)
        {
            var resultado = false;
            try 
	        {	        
                var isValidEmailAddress = Email.ValidateEmailAddress( usuario.Email );
                if ( !isValidEmailAddress )
                    return false;

	            var asunto = "Recuperación de password";

                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;' >Datos del Usuario</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%' >");
                    sb.Append("<colgroup><col width='30%' /><col width='30%' /><col width='40%' /></colgroup>");
                    sb.Append("<tr>");    
                    sb.Append("<thead>");
                    sb.Append("<th>Usuario</th>");
	                sb.Append("<th>Password</th>");
                    sb.Append("<th>Email</th>");
                    sb.Append("</thead>");    
                    sb.Append("</tr>");    
                    sb.Append("<tbody>");
                    sb.Append("<tr style='text-align:center'>");
                    sb.Append("<td>" + usuario.NombreUsuario + "</td>");
                    sb.Append("<td>" + usuario.Password + "</td>");
                    sb.Append("<td>" + usuario.Email + "</td>");
                    sb.Append("</tr>");
                    sb.Append("</tbody>");
                    sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();

                var destinatarios = MailHelper.CreateRecipientsList(usuario.Email, usuario.Descriptor);

                var asyncObjectInfo = new Email.AsyncSendMailCompletedObject()
                {     
                    Object = new MailInternalData(idEstudio, WellKnownKeys.Entities.TiposNotificacion.RESET_PASSWORD_USUARIO.Id, DeliveryType.Mail, usuario),
                    OnCompleted = MailHelper.OnEnvioMailCompletado
                };

	            resultado = MailClient().SendMail(destinatarios, asunto, cuerpo, asyncObjectInfo);
            }
            catch (Exception ex)
            {
                throw;
            }
            return resultado;
        }

        /// <summary>
        /// Enviar Mail de Reclamo
        /// </summary>
        /// <param name="reclamo"></param>
        /// <param name="emisorEsProveedor"></param>
        /// <returns></returns>
        public static bool EnviarMailReclamo(Reclamo reclamo, bool emisorEsProveedor)
        {
            var resultado = false;
            try 
	        {
                var currentSession = SessionHelper.GetCurrentSessionInfo();
                if (currentSession == null)
                    return false;

	            if (reclamo == null || reclamo.Items == null || reclamo.Items.Count == 0 )
	                return false;

	            var estudio = new ControladorBase<Estudio>().ObtenerEntidad(x => x.Id == currentSession.Studio.Id);

	            var emailReclamos   = estudio.Emails.EmailReclamos;

	            var tituloGuion     = reclamo.Pago.Guion.Titulo + " - " + reclamo.Pago.Guion.Episodio;
	            var descripcion     = reclamo.Items.Last().Mensaje;
	            var fecha           = DateTime.Now;

	            var destinatarios   = default(Dictionary<string, string>);
	            var asunto          = String.Empty;

	            if (reclamo.Items.Count == 1)
	            {
                    destinatarios   = MailHelper.CreateRecipientsList(emailReclamos, "Reclamos");
	                asunto          = reclamo.Pago.Proveedor.MostrarNombreCompleto() + " ha enviado un reclamo.";
	            }
	            else
	            {
                    var emailDestinatario   = String.Empty;
                    var nombreDestinatario  = String.Empty;
                    if ( emisorEsProveedor )
                    {
                        emailDestinatario   = emailReclamos;
                        nombreDestinatario  = "Manager";
                    }
                    else
                    {
                        emailDestinatario   = reclamo.Pago.Proveedor.Email;
                        nombreDestinatario  = "Proveedor - " + reclamo.Pago.Proveedor.MostrarNombreCompleto();
                    }
                    destinatarios = MailHelper.CreateRecipientsList(emailDestinatario, nombreDestinatario);
                    asunto = String.Format("Respuesta del reclamo del {0}", reclamo.Fecha.ToShortDateString());
	            }

                var isValidEmailAddress = Email.ValidateEmailAddress( destinatarios.Keys.First() );
                if ( !isValidEmailAddress )
                    return false;

                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size:12px;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;' >Datos del reclamo</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%' >");
                    sb.Append("<colgroup><col width='100%' /></colgroup>");
                    sb.Append("<tr><td><label>Fecha:</label></td></tr>");
                    sb.Append("<tr><td><input type='text' style='width:98%' readonly='readonly' value='" + fecha.ToShortDateString() + "' /></td></tr>");
                    sb.Append("<tr><td><label>Asunto:</label></td></tr><tr>");
                    sb.Append("<td><input type='text' style='width:98%' readonly='readonly' value='" + tituloGuion + "' /></td></tr>");
                    sb.Append("<tr><td><label>Descripción:</label></td></tr><tr>");
                    sb.Append("<td><textarea style='width:98%' readonly='readonly' >" + descripcion + "</textarea></td></tr>");
                    sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();

	            var idEstudio = reclamo.Pago.Guion.Proyecto.Estudio.Id;

                var asyncObjectInfo = new Email.AsyncSendMailCompletedObject()
                {     
                    Object = new MailInternalData(idEstudio, WellKnownKeys.Entities.TiposNotificacion.RECLAMO_REALIZADO.Id, DeliveryType.Mail, reclamo),
                    OnCompleted = MailHelper.OnEnvioMailCompletado
                };

	            resultado = MailClient().SendMail(destinatarios, asunto, cuerpo, asyncObjectInfo);
	        }
            catch (Exception ex)
            {
                //throw; <== trap exception to avoid code flow interruption
                BasePage.LogError(ex);
            }
            return resultado;
        }

        /// <summary>
        /// Enviar mail de Solicitud Autorización de Guión
        /// </summary>
        /// <param name="destinatarios"></param>
        /// <param name="guion"></param>
        /// <param name="tipoAutorizacion"></param>
        /// <param name="usuarioEmisor"></param>
        /// <param name="usuarioNotificado"></param>
        /// <returns></returns>
        public static bool EnviarMailSolicitudAutorizacionGuion(Dictionary<string, string> destinatarios, string guion, string tipoAutorizacion, string usuarioEmisor, string usuarioNotificado)
        {
            var resultado = false;
            try 
	        {	        
                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size:12px;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;' >Solicitud de autorización de Guión</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%' >");
                    sb.Append("<colgroup><col width='100%' /></colgroup>");
                    sb.Append("<tr><td><span>Tipo de autorización:</span>&nbsp;<span><b>" + tipoAutorizacion + "</b></span></td></tr>");
                    sb.Append("<tr><td><span>Notificado por:</span>&nbsp;<span><b>" + usuarioEmisor + "</b></span></td></tr>");
                    sb.Append("<tr><td><span>Guión:</span>&nbsp;<span><b>" + guion + "</b></span></td></tr>");
                    sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();

	            var asunto = String.Format("Se ha Notificado al usuario {0} una autorización de {1} para el guión: {2}.", usuarioNotificado, tipoAutorizacion, guion);

                resultado = MailClient().SendMail(destinatarios, asunto, cuerpo);
            }
            catch (Exception)
            {
	            throw;
            }
            return resultado;
        }

        /// <summary>
        /// Enviar mail de reclamo
        /// </summary>
        /// <param name="guion"></param>
        /// <returns></returns>
        public static bool EnviarMailNotificacionGuionFinalizado(Guion guion)
        {
            var resultado = false;
            try
            {
                var currentSession = Helpers.SessionHelper.GetCurrentSessionInfo();
                if (currentSession == null)
                    return false;

                if (guion == null)
                    return false;

                if (guion.Estado.Id != WellKnownKeys.Entities.EstadosGuion.FINALIZADO.Id)
                    return false;

                var estudio = new ControladorBase<Estudio>().ObtenerEntidad(x => x.Id == currentSession.Studio.Id);

                var programa    = guion.Titulo + " - Episodio " + guion.Episodio;
                var director    = guion.Director.MostrarNombreCompleto();
                var asunto      = String.Format("El Director {0} ha terminado el programa {1}.", director.ToUpper(), programa.ToUpper());
                var fecha       = guion.FechaTerminacion.Value;
                
                var destinatarios = MailHelper.CreateRecipientsList(estudio.Emails.EmailDirectores, "Directores");

                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size:12px;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;' >Terminación de Programa</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%' >");
                    sb.Append("<colgroup><col width='100%' /></colgroup>");
                    sb.Append("<tr><td><label>Fecha:</label></td></tr>");
                    sb.Append("<tr><td><input type='text' style='width:98%' readonly='readonly' value='" + fecha.ToShortDateString() + "' /></td></tr>");
                    sb.Append("<tr><td><label>Asunto:</label></td></tr><tr>");
                    sb.Append("<td><input type='text' style='width:98%' readonly='readonly' value='" + asunto + "' /></td></tr>");
                    sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();

	            var idEstudio = guion.Proyecto.Estudio.Id;

                var asyncObjectInfo = new Email.AsyncSendMailCompletedObject()
                {     
                    Object = new MailInternalData(idEstudio, WellKnownKeys.Entities.TiposNotificacion.FINALIZACION_GUION.Id, DeliveryType.Mail, guion),
                    OnCompleted = MailHelper.OnEnvioMailCompletado
                };

	            resultado = MailClient().SendMail(destinatarios, asunto, cuerpo, asyncObjectInfo);
	        }
            catch (Exception ex)
            {
                //throw; <== trap exception to avoid code flow interruption
                BasePage.LogError(ex);
            }
            return resultado;
        }

        /// <summary>
        /// Envía Mail notificando el Pago de un Guión
        /// </summary>
        /// <param name="pago"></param>
        /// <returns></returns>
        public static bool EnviarMailNotificacionGuionPagado(Pago pago)
        {
            var resultado = false;
            try
            {
                var isValidEmailAddress = Email.ValidateEmailAddress( pago.Proveedor.Email );
                if ( !isValidEmailAddress )
                    return false;

                var destinatarios   = MailHelper.CreateRecipientsList( pago.Proveedor.Email, pago.Proveedor.Descriptor );
                var asunto          = "Notificación de pago realizado";
                var programa        = String.Format("Ep. {0} - {1}", pago.Guion.Episodio, pago.Guion.Titulo);
                var fechaGuion      = pago.Guion.FechaCreacion;
                var fechaPago       = DateTime.Now;
                var medioPago       = pago.MedioPago.Nombre;
                var loops           = pago.Loops;
                var importe         = pago.ImporteTotal;

                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size:12px;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;padding: 5px; margin: 5px;' >Detalle de los pagos realizados</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%'><colgroup><col width='40%'><col width='10%'><col width='10%'><col width='10%'><col width='10%'><col width='20%'><col width='10%'></colgroup>");
                    sb.Append("<thead>");
	                sb.Append("<tr>");
                    sb.Append("<th>Programa</th>");
                    sb.Append("<th>Fecha</th>");
                    sb.Append("<th>Loops</th>");
                    sb.Append("<th>Importe</th>");
                    sb.Append("<th>Medio Pago</th>");
                    sb.Append("<th>Fecha Pago</th>");
	                sb.Append("</tr>");
                    sb.Append("</thead>");
	                sb.Append("<tbody>");
                    sb.Append("<tr style='text-align:center'>");
                    sb.Append("<td>" + programa +"</td>");
                    sb.Append("<td>" + fechaGuion.ToShortDateString() + "</td>");
                    sb.Append("<td>" + loops + "</td>");
                    sb.Append("<td>" + importe + "</td>");
                    sb.Append("<td>" + medioPago + "</td>");
                    sb.Append("<td>" + fechaPago.ToShortDateString() + "</td>");
                    sb.Append("</tr>");
                    sb.Append("</tbody>");
	                sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();

                var idEstudio = pago.Guion.Proyecto.Estudio.Id;

                var asyncObjectInfo = new Email.AsyncSendMailCompletedObject()
                {     
                    Object = new MailInternalData(idEstudio, WellKnownKeys.Entities.TiposNotificacion.PAGO_REALIZADO.Id, DeliveryType.Mail, pago),
                    OnCompleted = MailHelper.OnEnvioMailCompletado
                };

	            resultado = MailClient().SendMail(destinatarios, asunto, cuerpo, asyncObjectInfo);
	        }
            catch (Exception ex)
            {
                //throw; <== trap exception to avoid code flow interruption
                BasePage.LogError(ex);
            }
            return resultado;
        }

        /// <summary>
        /// Envía SMS notificando el Pago de un Guión
        /// </summary>
        /// <param name="pago"></param>
        /// <returns></returns>
        public static bool EnviarSmsNotificacionGuionPagado(Pago pago)
        {
            var resultado = false;
            try
            {
                var idEstudio = pago.Guion.Proyecto.Estudio.Id;

                var parametro = new ControladorBase<Parametro>().ObtenerEntidad(x => x.Estudio.Id == idEstudio);
                if (parametro == null)
                    return false;

                var isValidMobilePhone = Phone.ValidatePhoneNumber(Phone.PhoneType.Mobile, pago.Proveedor.Celular);
                if ( !isValidMobilePhone )
                    return false;

                var destinatarios = new Dictionary<string, string>
                {
                    {String.Format(parametro.SMSNumero, pago.Proveedor.Celular), String.Empty}
                };

                var asunto  =   parametro.SMSClave;
                var cuerpo  =   "Recibiste un pago de Caja de Ruidos!" + Environment.NewLine + Environment.NewLine +
                                String.Format("El proyecto '{0}' fue pagado en {1}. ", pago.Guion.Proyecto.Nombre, pago.MedioPago.Nombre ) +
                                "El detalle se encuentra disponible en tu correo." + Environment.NewLine +
                                "Saludos!";

                var asyncObjectInfo = new Email.AsyncSendMailCompletedObject()
                {     
                    Object = new MailInternalData(idEstudio, WellKnownKeys.Entities.TiposNotificacion.PAGO_REALIZADO.Id, DeliveryType.Sms, pago),
                    OnCompleted = MailHelper.OnEnvioMailCompletado
                };

	            resultado = MailClient().SendMail(destinatarios, asunto, cuerpo, asyncObjectInfo);
	        }
            catch (Exception ex)
            {
                //throw; <== trap exception to avoid code flow interruption
                BasePage.LogError(ex);
            }
            return resultado;
        }

        /// <summary>
        /// Callback function raised when an async mail sending is completed
        /// </summary>
        /// <param name="resultado"></param>
        /// <param name="mailMessage"></param>
        /// <param name="obj"></param>
        /// <param name="logErrorFunction"></param>
        public static void OnEnvioMailCompletado(bool resultado, MailMessage mailMessage, object obj, Action<Exception> logErrorFunction = null)
        {
            try
            {
                if (obj == null)
                    return;

                var mailInternalData = obj as MailInternalData;
                if (mailInternalData == null)
                    return;

                var estudio = new ControladorBase<Estudio>().ObtenerEntidad(mailInternalData.IdEstudio);
                var tipoNotificacion = new ControladorBase<NotificacionTipo>().ObtenerEntidad(mailInternalData.IdTipoNotificacion);

                var delivery = CreateDelivery(mailInternalData.DeliveryType, mailMessage, estudio, tipoNotificacion, resultado);
                
                switch (mailInternalData.IdTipoNotificacion)
                {
                    case WellKnownKeys.Entities.TiposNotificacion.RESET_PASSWORD_USUARIO.Id:
                        var usuario = new ControladorBase<Usuario>().ObtenerEntidad(((Usuario) mailInternalData.Data).Id);
                        CreateDeliveryUsuario(delivery, usuario);
                        break;

                    case WellKnownKeys.Entities.TiposNotificacion.FINALIZACION_GUION.Id:
                        var guion = new ControladorBase<Guion>().ObtenerEntidad(((Guion) mailInternalData.Data).Id);
                        CreateDeliveryGuion(delivery, guion);
                        break;

                    case WellKnownKeys.Entities.TiposNotificacion.RECLAMO_REALIZADO.Id:
                        var reclamo = new ControladorBase<Reclamo>().ObtenerEntidad(((Reclamo) mailInternalData.Data).Id);
                        CreateDeliveryReclamo(delivery, reclamo);
                        break;

                    case WellKnownKeys.Entities.TiposNotificacion.PAGO_REALIZADO.Id:
                        var pago = new ControladorBase<Pago>().ObtenerEntidad(((Pago) mailInternalData.Data).Id);
                        CreateDeliveryPago(delivery, pago);
                        break;
                }

            }
            catch (Exception ex)
            {
                //throw; <== trap exception to avoid code flow interruption
                if ( logErrorFunction != null )
                    logErrorFunction(ex);
            }
            finally
            {
                mailMessage.Dispose();
                if (obj != null)
                {
                    ((IDisposable) obj).Dispose();
                }
            }
        }

        #endregion

        #region Private Methods
        
        private static Email MailClient()
        {
            Email email = null;
            try
            {
                var parametroInfo = Helpers.SessionHelper.GetCurrentSessionInfo().Settings;
                if (parametroInfo != null)
                {
                    email = new Email
                            (
                                parametroInfo.EmailNombre,
                                parametroInfo.EmailNombreUsuario,
                                parametroInfo.EmailPassword,
                                parametroInfo.EmailSMTP,
                                parametroInfo.EmailPuerto,
                                parametroInfo.EmailHabilitarSSL
                            );
                }
            }
            catch (Exception ex)
            {
                // throw ex;
                BasePage.LogError( ex );
            }
            return email;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="resultado"></param>
        /// <param name="mailMessage"></param>
        /// <param name="obj"></param>
        /// <param name="logErrorFunction"></param>
        private static void OnEnvioMailCompletadoEmpty(bool resultado, MailMessage mailMessage, object obj, Action<Exception> logErrorFunction = null)
        {
            try
            {
            }
            catch (Exception ex)
            {
                //throw; <== trap exception to avoid code flow interruption
                if ( logErrorFunction != null )
                    logErrorFunction(ex);
            }
        }

        private static Delivery CreateDelivery(DeliveryType deliveryType, MailMessage mailMessage, Estudio estudio, NotificacionTipo tipoNotificacion, bool resultadoEnvio)
        {
            var delivery = default(Entidad);

            switch (deliveryType)
            {
                case DeliveryType.Mail:
                    var mail = new Mail()
                    {
                        Estudio = estudio,
                        NotificacionTipo = tipoNotificacion,
                        Fecha = DateTime.Now,
                        Asunto = mailMessage.Subject,
                        Cuerpo = mailMessage.Body,
                        Destinatarios = mailMessage.GetRecipients(),
                        Resultado = resultadoEnvio
                    };
                    new ControladorBase<Mail>().GuardarEntidad(mail);
                    delivery = mail;
                    break;

                case DeliveryType.Sms:
                    var sms = new Sms()
                    {
                        Estudio = estudio,
                        NotificacionTipo = tipoNotificacion,
                        Fecha = DateTime.Now,
                        Mensaje = mailMessage.Body,
                        Destinatario = mailMessage.GetRecipients(),
                        Resultado = resultadoEnvio
                    };
                    new ControladorBase<Sms>().GuardarEntidad(sms);
                    delivery = sms;
                    break;
            }

            return new Delivery(deliveryType, delivery);
        }

        private static bool CreateDeliveryPago(Delivery delivery, Pago pago)
        {
            var resultado = false;

            switch (delivery.DeliveryType)
            {
                case DeliveryType.Mail:
                    var mail = (Mail) delivery.Entity;
                    var controladorMailPago = new ControladorBase<MailPago>();
                    var mailPago = new MailPago
                    {
                        Mail = mail,
                        Pago = pago
                    };
                    resultado = controladorMailPago.GuardarEntidad(mailPago);                    
                    break;

                case DeliveryType.Sms:
                    var sms = (Sms) delivery.Entity;
                    var controladorSmsPago = new ControladorBase<SmsPago>();
                    var smsPago = new SmsPago
                    {
                        Sms = sms,
                        Pago = pago
                    };
                    resultado = controladorSmsPago.GuardarEntidad(smsPago);                    
                    break;
            }

            return resultado;
        }
 
        private static bool CreateDeliveryUsuario(Delivery delivery, Usuario usuario)
        {
            var resultado = false;

            switch (delivery.DeliveryType)
            {
                case DeliveryType.Mail:
                    var mail = (Mail) delivery.Entity;
                    var controladorMailUsuario = new ControladorBase<MailUsuario>();
                    var mailUsuario = new MailUsuario
                    {
                        Mail = mail,
                        Usuario = usuario
                    };
                    resultado = controladorMailUsuario.GuardarEntidad(mailUsuario);                    
                    break;

                case DeliveryType.Sms:
                    var sms = (Sms) delivery.Entity;
                    var controladorSmsUsuario = new ControladorBase<SmsUsuario>();
                    var smsUsuario = new SmsUsuario
                    {
                        Sms = sms,
                        Usuario = usuario
                    };
                    resultado = controladorSmsUsuario.GuardarEntidad(smsUsuario);                    
                    break;
            }

            return resultado;
        }

        private static bool CreateDeliveryGuion(Delivery delivery, Guion guion)
        {
            var resultado = false;

            switch (delivery.DeliveryType)
            {
                case DeliveryType.Mail:
                    var mail = (Mail) delivery.Entity;
                    var controladorMailGuion = new ControladorBase<MailGuion>();
                    var mailGuion = new MailGuion()
                    {
                        Mail = mail,
                        Guion = guion
                    };
                    resultado = controladorMailGuion.GuardarEntidad(mailGuion);                    
                    break;

                case DeliveryType.Sms:
                    var sms = (Sms) delivery.Entity;
                    var controladorSmsGuion = new ControladorBase<SmsGuion>();
                    var smsGuion = new SmsGuion()
                    {
                        Sms = sms,
                        Guion = guion
                    };
                    resultado = controladorSmsGuion.GuardarEntidad(smsGuion);                    
                    break;
            }

            return resultado;
        }

        private static bool CreateDeliveryReclamo(Delivery delivery, Reclamo reclamo)
        {
            var resultado = false;

            switch (delivery.DeliveryType)
            {
                case DeliveryType.Mail:
                    var mail = (Mail) delivery.Entity;
                    var controladorMailReclamo = new ControladorBase<MailReclamo>();
                    var mailReclamo = new MailReclamo()
                    {
                        Mail = mail,
                        Reclamo = reclamo
                    };
                    resultado = controladorMailReclamo.GuardarEntidad(mailReclamo);                    
                    break;

                case DeliveryType.Sms:
                    var sms = (Sms) delivery.Entity;
                    var controladorSmsReclamo = new ControladorBase<SmsReclamo>();
                    var smsReclamo = new SmsReclamo()
                    {
                        Sms = sms,
                        Reclamo = reclamo
                    };
                    resultado = controladorSmsReclamo.GuardarEntidad(smsReclamo);                    
                    break;
            }

            return resultado;
        }

        #endregion
    }
}